# -*- coding: utf-8 -*-

import json

from django.utils.decorators import method_decorator
from django.utils.encoding import smart_unicode
from django.views.decorators.http import require_POST, require_GET
from django.views.generic import TemplateView

from common.console import db
from common.utils import exceptions as err
from common.utils import track_logging
from common.utils.api import check_params, token_required
from common.utils.decorator import response_wrapper
from common.utils.respcode import StatusCode
from common.utils.tz import utc_to_local_str

_LOGGER = track_logging.getLogger(__name__)


@require_POST
@response_wrapper
def login(req):
    ''' 用户登陆 '''
    query_dct = json.loads(req.body)
    check_params(query_dct, ('username', 'password'))

    user = db.login_user(query_dct['username'],
                         query_dct['password'])

    try:
        user['perm'] = [int(x) for x in db.get_role(user['role']).as_dict()['permissions'].split(',')]
    except:
        pass
    return user


@require_POST
@response_wrapper
@token_required
def logout(req):
    ''' 用户登出 '''
    db.logout_user(req.user_id)
    return {}


class UserView(TemplateView):
    def post(self, req):
        ''' 注册用户 '''
        query_dct = json.loads(req.body)
        check_params(query_dct, ('username', 'password'), {
            'nickname': ''
        })
        query_dct['nickname'] = smart_unicode(query_dct['nickname'])
        db.create_user(query_dct['username'], query_dct['password'],
                       query_dct['nickname'])

        _LOGGER.info('register user: %s', query_dct)
        return {}

    @method_decorator(response_wrapper)
    def dispatch(self, *args, **kwargs):
        return super(UserView, self).dispatch(*args, **kwargs)


@require_POST
@response_wrapper
@token_required
def modify(req):
    ''' 修改用户信息'''
    query_dct = json.loads(req.body)

    valid_params = {}
    valid_params['id'] = int(req.user_id)
    for k in ('nickname', 'password'):
        if k in query_dct:
            valid_params[k] = query_dct[k]

    if 'password' in valid_params:
        check_params(query_dct, ('old_password',))
        user = req.user
        if db.encode_password(query_dct['old_password']) != user.password:
            raise err.AuthenticateError(status=StatusCode.WRONG_PASSWORD)

    if 'nickname' in valid_params:
        valid_params['nickname'] = smart_unicode(
            valid_params['nickname'])

    db.update_user(int(req.user_id), valid_params)

    if 'password' in valid_params:
        db.logout_user(req.user_id)

    _LOGGER.info('modify user: %s, by %s', query_dct, req.user.id)
    return {}


class SingleUserView(TemplateView):
    def get(self, req, user_id):
        ''' 获取用户信息 '''
        user_id = long(user_id)

        info = db.get_user(user_id).as_dict()
        if req.user.id != user_id and req.user.role < info['role']:
            raise err.PermissionError()
        else:
            info.pop('password', None)
            info.pop('deleted', None)
            info['perm'] = [int(x) for x in db.get_role(info['role']).as_dict()['permissions'].split(',')]
            info['created_at'] = utc_to_local_str(info['created_at'])
            info['updated_at'] = utc_to_local_str(info['updated_at'])
            return info

    def put(self, req, user_id):
        ''' 修改用户信息'''
        query_dct = json.loads(req.body)
        # 此接口只能修改自己的用户属性
        if req.user.id != int(user_id):
            raise err.PermissionError('user_id not match')

        valid_params = {}
        valid_params['id'] = int(user_id)
        for k in ('nickname', 'password'):
            if k in query_dct:
                valid_params[k] = query_dct[k]

        if 'password' in valid_params:
            check_params(query_dct, ('old_password',))
            user = req.user
            if db.encode_password(query_dct['old_password']) != user.password:
                raise err.AuthenticateError(status=StatusCode.WRONG_PASSWORD)

        if 'nickname' in valid_params:
            valid_params['nickname'] = smart_unicode(
                valid_params['nickname'])

        db.update_user(int(user_id), valid_params)

        if 'password' in valid_params:
            db.logout_user(req.user_id)

        _LOGGER.info('update user: %s, by %s', query_dct, req.user.id)
        return {}

    @method_decorator(response_wrapper)
    @method_decorator(token_required)
    def dispatch(self, *args, **kwargs):
        return super(SingleUserView, self).dispatch(*args, **kwargs)


@require_GET
@response_wrapper
@token_required
def get_user_list(req):
    ''' 获取用户列表 '''
    query_dct = req.GET.dict()
    items, total_count = db.list_users(query_dct)
    resp_items = []
    for item in items:
        data = item.as_dict()
        data.pop('password', None)
        data.pop('deleted', None)
        data['updated_at'] = utc_to_local_str(data['updated_at'])
        data['created_at'] = utc_to_local_str(data['created_at'])
        resp_items.append(data)

    return {'list': resp_items, 'page': query_dct.get('$page', 1),
            'size': len(resp_items), 'total_count': total_count}


@require_GET
@response_wrapper
@token_required
def get_user_info(req, user_id):
    info = db.get_user(user_id).as_dict()
    info.pop('password', None)
    info.pop('deleted', None)
    info.pop('created_at', None)
    info.pop('updated_at', None)
    return info


@require_POST
@response_wrapper
@token_required
def update_user_info(req, user_id):
    ''' 修改用户信息'''
    query_dct = json.loads(req.body)

    valid_params = {}
    for k in ('role', 'enabled', 'nickname'):
        if k in query_dct:
            valid_params[k] = query_dct[k]

    db.update_user(int(user_id), valid_params)

    # 管理员调整用户属性后强制登出
    db.logout_user(user_id)
    _LOGGER.info('update user: %s, by %s', query_dct, req.user.id)
    return {}


@require_POST
@response_wrapper
@token_required
def delete_user(req, user_id):
    ''' 删除用户 '''
    db.delete_user(int(user_id))
    return {}


@require_GET
@response_wrapper
@token_required
def get_role_list(req):
    ''' 获取角色列表 '''
    query_dct = req.GET.dict()
    query_dct["$page"] = '1'
    items, total_count = db.list_roles(query_dct)
    resp_items = []
    for item in items:
        data = item.as_dict()
        data.pop('deleted', None)
        data['updated_at'] = utc_to_local_str(data['updated_at'])
        data['created_at'] = utc_to_local_str(data['created_at'])
        data['permissions'] = data['permissions'].split(',')
        resp_items.append(data)

    return {'list': resp_items, 'page': query_dct.get('$page', 1),
            'size': len(resp_items), 'total_count': total_count}


@require_POST
@response_wrapper
@token_required
def update_role_info(req, role_id):
    ''' 修改角色信息'''
    query_dct = json.loads(req.body)

    valid_params = {}
    for k in ('rolename', 'permissions', 'mch_ids', 'enabled', 'deleted'):
        if k in query_dct:
            valid_params[k] = query_dct[k]

    db.update_role(int(role_id), valid_params)

    _LOGGER.info('update role: %s %s, by %s', role_id, query_dct, req.user.id)
    return {}


@require_GET
@response_wrapper
@token_required
def get_role(req, role_id):
    ''' 获取角色详情 '''
    role = db.get_role(int(role_id))
    role_data = role.as_dict()
    role_data['permissions'] = role_data['permissions'].split(',')
    return role_data


@require_POST
@response_wrapper
@token_required
def create_role(req):
    ''' 创建角色 '''
    query_dct = json.loads(req.body)
    check_params(query_dct, ('rolename', 'permissions'))
    role_data = db.create_role(
        query_dct['rolename'], query_dct['permissions'], query_dct.get('mch_ids', '')).as_dict()
    _LOGGER.info('create role: %s, by %s', query_dct, req.user.id)
    return {}


@require_POST
@response_wrapper
@token_required
def delete_role(req, role_id):
    ''' 删除角色 '''
    db.delete_role(int(role_id))
    _LOGGER.info('delete role: %s by %s', role_id, req.user.id)
    return {}


@require_GET
@response_wrapper
@token_required
def list_perm_mod(req):
    ''' 获取权限大模块列表 '''
    return db.list_perm_mod()


@require_GET
@response_wrapper
@token_required
def list_perm(req):
    ''' 获取权限列表 '''
    query_dct = req.GET.dict()
    if '$size' not in query_dct:
        query_dct['$size'] = '-1'
    items, total_count = db.list_perm(query_dct)
    resp_items = []
    for item in items:
        data = item.as_dict()
        data['updated_at'] = utc_to_local_str(data['updated_at'])
        data['created_at'] = utc_to_local_str(data['created_at'])
        resp_items.append(data)

    return {'list': resp_items, 'page': query_dct.get('$page', 1),
            'size': len(resp_items), 'total_count': total_count}


@require_GET
@response_wrapper
@token_required
def list_perm_tree(req):
    resp = {}
    perm_mods = db.list_perm_mod()
    for mod, mod_name in perm_mods.iteritems():
        resp[mod] = {'name': mod_name, 'permissions': []}
    items, total_count = db.list_perm({'$size': '-1'})
    for item in items:
        resp[item.permission_mod]['permissions'].append({
            "name": item.desc.encode('utf-8'),
            "id": item.id
        })
    resp1 = []
    for k, v in resp.items():
        resp1.append({'id': k, 'name': v['name'], 'permissions': v['permissions']})
    return resp1


@require_GET
@response_wrapper
@token_required
def list_records(req):
    query_dct = req.GET.dict()
    items, total_count = db.list_record(query_dct)

    resp_items = []
    for item in items:
        r, username = item
        data = r.as_dict()
        data['resource_id'] = str(data['resource_id'])
        data['username'] = username
        data['created_at'] = utc_to_local_str(r.created_at)
        resp_items.append(data)

    return {'list': resp_items, 'page': query_dct.get('$page', 1),
            'size': len(resp_items), 'total_count': total_count}
